package com.apexedu.sync.node.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.apexedu.biz.Const;
import com.apexedu.framework.dao.BaseDao;
import com.apexedu.framework.util.ConfigUtil;
import com.apexedu.framework.util.SysPropertiesUtil;
import com.apexedu.identity.IdConstants;
import com.apexedu.identity.entity.TSysMenu;
import com.apexedu.portal.util.DBMUtil;
import com.apexedu.sync.contant.Constants;
import com.apexedu.sync.engine.ISyncContext;
import com.apexedu.sync.entity.SyncAppModelMsg;
import com.apexedu.sync.exception.AuCSyncException;
import com.apexedu.sync.node.ISyncNode;
import com.apexedu.sys.SysConstant;
import com.apexedu.sys.util.BusinessLogUtil;

/**
 * 同步livebos系统菜单资源
 * Created by ly on 2015/1/12.
 */
public class LivebosMenuNode extends BaseNode implements ISyncNode {

	@Override
	public void execute(ISyncContext context) throws AuCSyncException {
		BaseDao baseDao = context.getBaseDao();
		DBMUtil dbmUtil = context.getDbmUtil();//多数据源工具类
		String msg;
		try {
			List<TSysMenu> menuList = new ArrayList<TSysMenu>();
			List<TSysMenu> list = null;
			String dbType = context.getDbmUtil().getDbType(); //数据库类型
			String sql = "";
			if ("false".equals(SysPropertiesUtil.get(IdConstants.IS_MULTI_SCHEME))) { //单方案，交院用
				if (Const.DbType.ORACLE.equals(dbType)) {
					sql += " select id as menuid,fid as upmenuid,fid as upbizcode,title as menuname,\"LEVEL\" as depth";
					sql += " ,? as belongtoapp";
					sql += " ,case when tablename is null then id||'' else tablename end as bizcode";
					sql += " ,case when tablename is null then id||'' else tablename end as menupath";
					sql += " ,1 as state,1 as srctype,0 as isshare";
					sql += " from  tmenu t";
					sql += " order by \"LEVEL\" ";
				} else if (Const.DbType.SQLSERVER.equals(dbType)) {
					sql += " select id as menuid,fid as upmenuid,fid as upbizcode,title as menuname,\"LEVEL\" as depth";
					sql += " ,? as belongtoapp";
					sql += " ,case when tablename='' then convert(varchar,id) else tablename end as bizcode";
					sql += " ,case when tablename='' then convert(varchar,id) else tablename end as menupath";
					sql += " ,1 as state,1 as srctype,0 as isshare";
					sql += " from  tmenu t";
					sql += " order by \"LEVEL\" ";
				}
				list = dbmUtil.queryAllBeanList(sql, TSysMenu.class, context.getAppid());
			} else { //多方案
				sql += " select a.tablename||'' as menuid,tt.id as upmenuid,a.tablename as bizcode,";
				sql += " tt.id as upbizcode,a.describe as menuname,";
				sql += " a.tablename as menupath,? as belongtoapp,3 as depth,1 as state,1 as srctype,0 as isshare";
				sql += " from ttable a";
				sql += " left join (select t.*, level, ltrim(SYS_CONNECT_BY_PATH(packagepath, '.'),'.') as p";
				sql += " from tcategoryinfo t  START WITH pid=0 CONNECT BY PRIOR id = pid) tt on a.packagepath=tt.p";
				sql += " union ";
				sql += " select id||'' as menuid,pid as upmenuid,id||'' as bizcode,pid as unbizcode,b.category as menuname,";
				sql += " '' as menupath,? as belongtoapp, case when pid=0 then 1 else 2 end as depth,1 as state,1 as srctype,0 as isshare";
				sql += " from tcategoryinfo b START WITH pid=0 CONNECT BY PRIOR id = pid";
				list = dbmUtil.queryAllBeanList(sql, TSysMenu.class, context.getAppid(), context.getAppid());
			}

			for (TSysMenu menu : list) {
				if (1 == menu.getDepth().intValue()) {
					menuList.add(menu);
				} else {
					setMenuTempList(menuList, menu);
				}
			}

			//根目录对象，其他所有菜单资源都添加到其子分类下
			TSysMenu rootMenu = new TSysMenu(getParentMenuId(context), menuList);
			//根菜单id
			String rootMenuId = rootMenu.getMenuid();
			//待保存的菜单list
			List<TSysMenu> needSavedMenuList = new ArrayList<TSysMenu>();
			//系统中缓存的菜单map
			Map<String, TSysMenu> cachedMenuMap = context.getMapMenu();
			/* 转换所有现有资源为菜单对象集合 */
			convertMenu(rootMenu, needSavedMenuList, rootMenuId, cachedMenuMap);

			/* 先删除原有资源 */
			String sql_deleteOld = "delete from TSysMenu where belongtoapp = ? and menuid != ?";
			int delete = baseDao.executeHql(sql_deleteOld, context.getAppid(), rootMenu.getMenuid());

			//保存现有资源
			baseDao.saveOrUpdateAll(needSavedMenuList);

			//删除已废弃的门户关联资源
			String portalid = ConfigUtil.getString("portalCode");
			String sql_deleteLink = "delete from TSysMenu a where a.belongtoapp=? and oldbelongtoapp=?" + " and not exists (select menuid from TSysMenu b where a.bizcode=b.bizcode and a.oldbelongtoapp=b.belongtoapp and b.belongtoapp=?)";
			baseDao.executeHql(sql_deleteLink, portalid, context.getAppid(), context.getAppid());

			//删除已废弃的用户订阅门户资源
			String sql_deleteRSS = "delete from TFwDy a where not exists (select menuid from TSysMenu b where a.menuid=b.menuid)";
			baseDao.executeHql(sql_deleteRSS);

			msg = "插入：" + needSavedMenuList.size() + "条, 删除：" + delete + "条";
			BusinessLogUtil.log(getUserInfo(context), SysConstant.CZDX_T_SYS_MENU, Const.LOG_ACTION_UPDATE, "", msg);
			context.getMsg().getListModelMsg().add(new SyncAppModelMsg(Constants.NodeType.MENU, msg));
		} catch (AuCSyncException e) {
			e.printStackTrace();
			log.error("LivebosMenuNode execute error : " + e);
			context.getMsg().getListModelMsg().add(new SyncAppModelMsg(Constants.NodeType.MENU, e.getMessage()));
			throw e;
		} catch (Exception e) {
			e.printStackTrace();
			log.error("LivebosMenuNode execute error : " + e);
			msg = e.getMessage();
			context.getMsg().getListModelMsg().add(new SyncAppModelMsg(Constants.NodeType.MENU, msg));
			throw new AuCSyncException(AuCSyncException.UNKNOWN_SERVICE_ERROR, msg);
		}
	}

	/**
	 * 设置菜单集合缓存
	 *
	 * @param menuList
	 * @param m
	 */
	private void setMenuTempList(List<TSysMenu> menuList, TSysMenu m) {
		for (TSysMenu t : menuList) {
			if (m.getUpmenuid().equals(t.getMenuid())) {
				t.getChildMenu().add(m);
				break;
			}
			if (!t.getChildMenu().isEmpty()) {
				setMenuTempList(t.getChildMenu(), m);
			}
		}
	}

	/**
	 * 转换临时对象为菜单资源信息，并保存到集合中(处理新增的数据)
	 *
	 * @param menu 菜单资源
	 * @param menuList 菜单资源list
	 * @param menuId 菜单资源id
	 * @param menuMap 菜单资源map
	 */
	public void convertMenu(TSysMenu menu, List<TSysMenu> menuList, String menuId, Map<String, TSysMenu> menuMap) throws AuCSyncException {
		if (menuId.length() > 6) {
			menu.setMenuid(menuId);
			menu.setUpmenuid(menuId.substring(0, menuId.length() - 3));//父节点i
			menu.setDepth((short) (menuId.length() / 3));
			menu.setOrdernum(10000 - Integer.parseInt(menu.getMenuid().substring(menu.getMenuid().length() - 2)) * 100);//默认排序值
			menuList.add(menu);
			String codeInBizApp = menu.getBizcode();
			if (null != menuMap.get(codeInBizApp)) {
				//throw new AuCSyncException(AuCSyncException.MENU_DUPLICATE, " 配置菜单重复！重复菜单代码：" + codeInBizApp);
			}
			menuMap.put(codeInBizApp, menu);
		}
		if (!menu.getChildMenu().isEmpty()) {
			for (int i = 0; i < menu.getChildMenu().size(); i++) {
				if (i < 9) {
					convertMenu(menu.getChildMenu().get(i), menuList, menuId + "00" + (i + 1), menuMap);
				} else if (i < 99) {
					convertMenu(menu.getChildMenu().get(i), menuList, menuId + "0" + (i + 1), menuMap);
				} else {
					convertMenu(menu.getChildMenu().get(i), menuList, menuId + (i + 1), menuMap);
				}
			}
		}
	}
}
